Skip to content

feat: add text/chunk connector for RAG ingest (#153)#170

Merged
michaelmcnees merged 1 commit into
mainfrom
claude/office-assistant-mantle-feasibility-n8f4bk
Jul 3, 2026
Merged

feat: add text/chunk connector for RAG ingest (#153)#170
michaelmcnees merged 1 commit into
mainfrom
claude/office-assistant-mantle-feasibility-n8f4bk

Conversation

@michaelmcnees

@michaelmcnees michaelmcnees commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Completes the RAG ingest pipeline: text/chunk -> ai/embed (batch) ->
kb/upsert (batch).

  • text/chunk splits a document into overlapping chunks by characters (Unicode-aware) or words, with configurable chunk_size/chunk_overlap. output.chunks feeds straight into ai/embed's input and kb/upsert's contents. Pure chunkText core with thorough unit tests (char/word, overlap, exact-fit, unicode, shorter-than-size, error cases).
  • kb/upsert: a single metadata object is now broadcast to every row of a batch, so chunked ingest can share one title/source. (metadatas still matches per-row.)
  • rag-ingest example rewritten to chunk -> embed -> upsert; text/chunk documented in the connector reference; RAG guide updated. rag-ingest passes mantle validate.

Smarter (separator-aware/token) chunking and kb/query metadata filtering remain follow-ups on #153.

Claude-Session: https://claude.ai/code/session_01WnKgCRfMvFcZAkoVbr8k79

Summary

What does this PR do?

Changes

  • ...

Testing

  • make test passes
  • make lint passes
  • New tests added for new functionality

Related Issues

Closes #

Summary by CodeRabbit

  • New Features

    • Added text chunking for long documents with overlapping, configurable chunk sizes and support for character or word-based splitting.
    • Enabled chunked RAG ingestion so document chunks can flow directly into embedding and storage steps in a single batch.
    • Allowed shared metadata to be applied across all items in a batch during knowledge base upserts.
  • Documentation

    • Updated RAG and connector docs with the new chunking workflow and examples.
  • Tests

    • Added coverage for chunking behavior, Unicode handling, validation errors, and batch metadata handling.

Completes the RAG ingest pipeline: text/chunk -> ai/embed (batch) ->
kb/upsert (batch).

- text/chunk splits a document into overlapping chunks by characters
  (Unicode-aware) or words, with configurable chunk_size/chunk_overlap.
  output.chunks feeds straight into ai/embed's input and kb/upsert's
  contents. Pure chunkText core with thorough unit tests (char/word,
  overlap, exact-fit, unicode, shorter-than-size, error cases).
- kb/upsert: a single `metadata` object is now broadcast to every row of a
  batch, so chunked ingest can share one title/source. (`metadatas` still
  matches per-row.)
- rag-ingest example rewritten to chunk -> embed -> upsert; text/chunk
  documented in the connector reference; RAG guide updated. rag-ingest
  passes `mantle validate`.

Smarter (separator-aware/token) chunking and kb/query metadata filtering
remain follow-ups on #153.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnKgCRfMvFcZAkoVbr8k79
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new text/chunk connector to the engine that splits text into overlapping chunks by characters or words, registers it in the connector registry, and updates kb/upsert's metadata handling to broadcast a single metadata object across batch rows. Documentation and the RAG example workflow are updated to reflect the new chunking-based ingestion flow.

Changes

Chunking connector and kb metadata broadcast

Layer / File(s) Summary
Chunk text utilities and connector
packages/engine/internal/connector/chunk.go, packages/engine/internal/connector/connector.go
Adds chunkText (input validation, chars/words unit support, overlap handling), sliceChunks windowing, and TextChunkConnector.Execute; registers text/chunk in NewRegistry.
Chunk connector tests
packages/engine/internal/connector/chunk_test.go
Adds tests for character/word/unicode chunking, edge cases, error validation, and connector output.
kb/upsert metadata broadcast logic
packages/engine/internal/connector/kb.go, packages/engine/internal/connector/kb_test.go
Refactors kbMetadata to handle single metadata broadcast versus metadatas array separately, with stricter validation; adds a broadcast test.
Docs and RAG example updates
.changeset/text-chunk-connector.md, packages/site/src/content/docs/rag-guide.md, packages/site/src/content/docs/workflow-reference/connectors.md, packages/site/src/content/examples/rag-ingest.yaml
Adds changeset, text/chunk connector reference docs, updated RAG guide notes, and a rewritten rag-ingest.yaml pipeline using chunk → batched embed → batched upsert.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • dvflw/mantle#169: Adds the kb/upsert connector and prepareUpsert logic that this PR's metadata broadcast changes directly build upon.

Poem

A rabbit chops text into neat little bits,
Overlapping chunks, no missing bits,
Off to embed, then off to store,
One metadata note, shared by all — no more!
🐇✂️📄 Hop, hop, ingest galore!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding the text/chunk connector for RAG ingestion.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/office-assistant-mantle-feasibility-n8f4bk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/site/src/content/docs/workflow-reference/connectors.md (1)

334-334: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

kb/upsert params table doesn't reflect new broadcast semantics.

The metadata / metadatas row still says "the count must match," but the new broadcast behavior means a single metadata object is applied to every row regardless of row count — only metadatas (array) must match one-to-one. This directly contradicts the # broadcast to every chunk example shown a few lines below (line 429) and in kb.go's updated kbMetadata doc comment.

📝 Proposed doc fix
-| `metadata` / `metadatas` | object / list | No | Optional JSONB metadata per row. If provided, the count must match. |
+| `metadata` | object | No | Optional JSONB metadata broadcast to every row (e.g. shared title/source for a batch). |
+| `metadatas` | list | No | Optional per-row JSONB metadata. Count must match `content`/`contents`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/site/src/content/docs/workflow-reference/connectors.md` at line 334,
Update the `metadata` / `metadatas` row in the `kb/upsert` params table to match
the new broadcast behavior: a single `metadata` object should be described as
applying to every row, while only `metadatas` (the array form) must match row
count one-to-one. Use the nearby `kb/upsert` examples and the `kbMetadata` docs
in `kb.go` as the source of truth, and remove the outdated “count must match”
wording for the singular `metadata` case.
🧹 Nitpick comments (1)
packages/engine/internal/connector/chunk.go (1)

54-69: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

High overlap ratios can cause quadratic memory blow-up.

step = size - overlap can be as small as 1 (overlap = size - 1), which makes sliceChunks emit roughly n chunks, each of length size. For a large document this yields O(n * size) total output memory — e.g. a 100k-character document with chunk_size=1000, chunk_overlap=999 would produce ~100k chunks of ~1000 chars each, well over 100MB. Since this connector feeds directly into ai/embed/kb/upsert batches, this could also translate into a very large downstream batch.

Consider bounding overlap to a fraction of size (e.g., overlap <= size/2) or documenting/capping the maximum chunk count.

♻️ Example validation to cap overlap ratio
 	if overlap >= size {
 		return nil, fmt.Errorf("chunk_overlap (%d) must be less than chunk_size (%d)", overlap, size)
 	}
+	if overlap > size/2 {
+		return nil, fmt.Errorf("chunk_overlap (%d) must not exceed half of chunk_size (%d) to avoid excessive chunk counts", overlap, size)
+	}
 	step := size - overlap
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/engine/internal/connector/chunk.go` around lines 54 - 69, The
sliceChunks helper can generate an excessive number of overlapping chunks when
step is very small, causing memory blow-up downstream in ai/embed and kb/upsert.
Update the chunking logic in sliceChunks (and the overlap-to-step calculation
that feeds it) to cap overlap to a safe fraction of size, such as at most half,
or otherwise enforce a maximum chunk count before emitting windows. Keep the
behavior centered around sliceChunks so the fix is applied where chunk emission
is controlled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/site/src/content/docs/workflow-reference/connectors.md`:
- Line 334: Update the `metadata` / `metadatas` row in the `kb/upsert` params
table to match the new broadcast behavior: a single `metadata` object should be
described as applying to every row, while only `metadatas` (the array form) must
match row count one-to-one. Use the nearby `kb/upsert` examples and the
`kbMetadata` docs in `kb.go` as the source of truth, and remove the outdated
“count must match” wording for the singular `metadata` case.

---

Nitpick comments:
In `@packages/engine/internal/connector/chunk.go`:
- Around line 54-69: The sliceChunks helper can generate an excessive number of
overlapping chunks when step is very small, causing memory blow-up downstream in
ai/embed and kb/upsert. Update the chunking logic in sliceChunks (and the
overlap-to-step calculation that feeds it) to cap overlap to a safe fraction of
size, such as at most half, or otherwise enforce a maximum chunk count before
emitting windows. Keep the behavior centered around sliceChunks so the fix is
applied where chunk emission is controlled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 550dd17c-89ee-48da-b2a9-0956f3a8a17b

📥 Commits

Reviewing files that changed from the base of the PR and between 9a7e8a8 and 1fc0beb.

📒 Files selected for processing (9)
  • .changeset/text-chunk-connector.md
  • packages/engine/internal/connector/chunk.go
  • packages/engine/internal/connector/chunk_test.go
  • packages/engine/internal/connector/connector.go
  • packages/engine/internal/connector/kb.go
  • packages/engine/internal/connector/kb_test.go
  • packages/site/src/content/docs/rag-guide.md
  • packages/site/src/content/docs/workflow-reference/connectors.md
  • packages/site/src/content/examples/rag-ingest.yaml

@michaelmcnees michaelmcnees merged commit 0f4a3f6 into main Jul 3, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants